"""文华商品指数的破解
化工品FU退出后，计算模式发生变化，需要暴力破解
"""
import numpy as np
import pandas as pd

from random import randint
from scipy.optimize import linprog

industrial = ['RU', 'AL', 'CU', 'FU', 'TA', 'ZN', 'L', 'RB', 'V', 'PB', 'J', 'FG', 'JM', 'BU', 'I', 'PP', 'HC', 'MA',
              'SF', 'SM', 'NI', 'SN', 'SC', 'SP', 'EG', 'UR', 'NR', 'SS', 'EB', 'SA', 'PG', 'LU', 'PF', 'SI', 'AO',
              'BR', 'LC', 'PX', 'SH']
agricultural = ["a", "c", "m", "RM", "PK", "y", "p", "OI", "CF", "SR", "JD", "cs", "AP", "CJ", "lh"]

commodity = industrial + agricultural

def calc_linalg(l, r):
    # 计算线性回归结果，l是参数，r是结果
    a = np.array(l)
    b = np.array(r)
    result = np.linalg.solve(a, b)
    return list(result)


def use_scipy_linprog(l, r):
    c = np.ones(len(r))
    constraints = {"type": "ineq", "fun": lambda x: x}
    a = np.array(l)
    b = np.array(r)
    result = linprog(c, A_ub=-a, b_ub=-b, bounds=(0, None))
    if result.success:
        return result.x
    else:
        return None


def calc_std(a, b):
    # 计算两个list的标准差
    dzip = zip(a, b)
    r = 0
    n = len(a)
    for r1, r2 in dzip:
        r += ((r1 - r2) * (r1 - r2)) / n
    return r ** 0.5


def use_power(src_data):
    # 等指数增长比例
    power_rate = 1.0000
    results = []

    for j in range(10000):
        pr = power_rate + j * 0.00001
        points_gap = []
        for n, rows in src_data.iterrows():
            dd = list(rows)
            point = dd.pop(-1)
            calc_point = 0
            for i in range(4):
                calc_point += pow(dd[i] * rate[i], pr) / 4
            # calc_point = pow(calc_point, pr)
            points_gap.append(abs(calc_point - point))
        std = np.mean(points_gap)
        r = {"power_date": pr, "std": std, "min": min(points_gap), "max": max(points_gap)}
        print(r, points_gap)
        results.append(r)
    df = pd.DataFrame(results)
    df.to_csv("d:\\daily work\\exp_result.csv")


def use_multiple(src_data):
    # 等倍数
    base_rate = 1.10500
    results = []

    for j in range(100):
        base_rate += 0.00001
        points_gap = []
        for n, rows in src_data.iterrows():
            dd = list(rows)
            point = dd.pop(-1)
            calc_point = 0
            for i in range(4):
                calc_point += dd[i] * rate[i] * base_rate / 4
            points_gap.append(abs(calc_point - point))
        std = np.mean(points_gap)
        r = {"base_rate": base_rate, "mean": std}
        print(r, points_gap)
        results.append(r)
    df = pd.DataFrame(results)
    df.to_csv("d:\\daily work\\use_multiple_result.csv")


rate = [0.010197287, 0.017760197, 0.01344388, 0.021717018]

if __name__ == "__main__":
    # src_data = pd.read_csv("d:\\daily work\\for_linalg.csv")
    # src_data.set_index("date", inplace=True)
    # use_power(src_data)
    # use_multiple(src_data)
    """
    data1 = pd.read_csv("d:\\daily work\\nonferrous\\data3.csv")
    data1.set_index("date", inplace=True)
    ls = []
    r = []
    for n, rows in data1.iterrows():
        dd = list(rows)
        r.append(dd.pop(-1))
        ls.append(dd)
    print(calc_linalg(ls, r))
    """
    """
    ls = [[16624.62,67453.2569,16812.8278,16940.323],
          [16566.5872,66164.3212,16510.3289,16623.0936],
          #[16852.8244,70855.1089,18252.4969,18677.0198],
          [16700.5509,66623.1817,16662.1595,16765.8657],
          #[16857.8505,71289.4797,18347.8572,18762.5647]
          [16701.9795,67139.933,16966.2707,17088.5786]
          ]
    r = [708.48,696.8,702.32,710.04]
    print(calc_linalg(ls, r))
    """
    #data1 = pd.read_csv("D:\daily work\文华商品指数\chemicals\\chemicals_test_data13.csv")
    # data1 = pd.read_csv("D:\daily work\文华商品指数\industrial\\wh_industrial_2020119.csv")
    # data1 = pd.read_csv("D:\daily work\文华商品指数\industrial\\industrial_test_data.csv")
    data1 = pd.read_csv("E:\daily work\文华商品指数\commodity\\commodity_prices.csv")
    data1.set_index("date", inplace=True)
    data_num = data1.shape[0]
    c_num = data1.shape[1] - 1
    print("data num:", data_num, "sec_num:", c_num)
    results = []
    columns = data1.columns.to_list()
    for i in range(200):
        chose_num = set()
        while (len(chose_num) < c_num):
            chose_num.add(randint(0, data_num - 1))
        ls = []
        r = []
        for num in chose_num:
            row = list(data1.iloc[num])
            r.append(row.pop(-1) * c_num)
            ls.append(row)
        rr = calc_linalg(ls, r)
        # rr = use_scipy_linprog(ls, r)
        if rr is None:
            continue
        print(rr)
        results.append(rr)
    result_df = pd.DataFrame(results, columns=columns[:-1])
    #result_df.to_csv("D:\daily work\文华商品指数\chemicals\\chemicals_test_result13.csv")
    # result_df.to_csv("D:\daily work\文华商品指数\industrial\\wh_industrial_2020119_result2.csv")
    # result_df.to_csv("D:\daily work\文华商品指数\industrial\\industrial_test_result2.csv")
    result_df.to_csv("E:\daily work\文华商品指数\commodity\\commodity_result.csv")
